/*
 * @FileName: [LoginController.java]
 * 
 * @Package com.bcinfo.upp.admin.ac.controller
 * 
 * 
 * Copyright (c) 2011-2015 BCINFO Technology Limited Com. All rights reserved.
 * 
 * This software is the confidential and proprietary information of BCINFO Technology Limited Company ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only in accordance with the terms of the contract agreement you entered into with RKY.
 * 
 * $Rev: 42 $ $LastChangedDate: 2013-10-12 10:19:36 +0800 (星期六, 12 十月 2013) $ $LastChangedBy: wanggc $
 * 
 * @category bcinfo-upp
 * 
 * @version 1.1
 * 
 * @author $Author: wanggc $
 * 
 * Change History:[Formatter: author date description] <br/> 1 2 3
 */

package com.bcinfo.iccard.admin.ac.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.bcinfo.iccard.admin.common.Constants;
import com.bcinfo.iccard.admin.common.ModuleEnum.Visit;
import com.bcinfo.iccard.admin.controller.AbstractController;
import com.bcinfo.upp.ac.model.Operator;
import com.bcinfo.upp.ac.model.RolePermission;
import com.bcinfo.upp.ac.service.OperatorService;
import com.bcinfo.upp.ac.service.PermissionService;
import com.bcinfo.upp.exception.UppDataBaseException;
import com.bcinfo.upp.exception.UppException;
import com.bcinfo.upp.sys.model.SysParameter;
import com.bcinfo.upp.sys.service.ConfigureService;
import com.bcinfo.upp.sys.service.MenuService;

/**
 * 登录控制器 <br/>
 * <p>
 * Description:<br/>
 * <p>
 * 登录和退出系统的控制器
 * 
 * <p>
 * For Examples <br/>
 * 
 * <PRE>
 *      http://127.0.0.1:8080/upp-admin/login
 * </PRE>
 * <p>
 */
@Controller
public class VisitController extends AbstractController
{
    @Autowired()
    private OperatorService   _operatorService;

    @Autowired()
    private MenuService       _menuSerice;

    @Autowired()
    private PermissionService _permissionService;

    @Autowired
    private ConfigureService  _configureService;

    /**
     * 
     * 执行登录操作(异步请求) <br/>
     * <p>
     * Description: 执行登录操作,登录成功后记录用户信息到session <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-23-下午4:09:11<br/>
     * <p>
     * 
     * @param session
     * @param user
     * @param pwd
     * @param imageCode
     * @return
     * 
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> login(String user, String pwd, String imageCode)
    {
        String imageCodeSession = (String) session.getAttribute("imageCode");
        Map<String, String> respMap = new HashMap<String, String>(2);

        try
        {
            if (!getImageCodeSwitch()
                    || (StringUtils.isNotBlank(imageCodeSession) && imageCodeSession.equalsIgnoreCase(imageCode)))
            {
                Operator operator = _operatorService.findByLoginName(user);
                if (null != operator && operator.getLoginPassword().equalsIgnoreCase(DigestUtils.md5Hex(pwd)))
                {
                    Long operatorId = operator.getOperatorId();
                    session.setAttribute(Constants.CURRENT_USER, operator);
                    session.setAttribute(Constants.CURRENT_USER_MENU, _menuSerice.listMenusByOptId(operatorId));
                    session.setAttribute(Constants.CURRENT_ROLE_PERMISSION,
                            convertRolePermission(_permissionService.listRolePermissionByOperator(operatorId)));
                    if (pwd.equalsIgnoreCase(Constants.DEFAULT_PASSWORD))
                    {
                        respMap = packageAjaxReturnMap("resetPwd", ERROR_VALUE_MSG_TYPE_INFO, null,
                                String.valueOf(operator.getOperatorId()));
                    }
                    else if (operator.getStatus() == 0)
                    {
                        respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_FAIL, ERROR_VALUE_MSG_TYPE_WARN,
                                "UserAlreadyForbidden", null);
                    }
                    else
                    {
                        respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_SUCCESS, ERROR_VALUE_MSG_TYPE_INFO, null,
                                "登录成功");
                        addLog(Visit.login, "operatorId=" + operator.getOperatorId() + "|desc=登录成功");
                    }
                }
                else
                {
                    respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_FAIL, ERROR_VALUE_MSG_TYPE_ERROR,
                            "VisitInvalidParametersException", null);
                }
            }
            else
            {
                respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_FAIL, ERROR_VALUE_MSG_TYPE_ERROR,
                        "ErrorImageCode", null);
            }
        }
        catch (UppException e)
        {
            respMap = packageUppException(e);
        }
        catch (Exception e)
        {
            respMap = packageException(e);
        }
        session.removeAttribute("imageCode");

        return respMap;
    }

    /**
     * 
     * 执行退出系统操作 (异步请求)<br/>
     * <p>
     * Description: 删除当前session的用户信息并返回结果 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-24-下午2:50:50<br/>
     * <p>
     * 
     * @param session
     * @return
     * 
     */
    @RequestMapping("/logout")
    @ResponseBody
    public Map<String, String> logout(HttpSession session)
    {
        Map<String, String> respMap = new HashMap<String, String>(2);
        session.removeAttribute(Constants.CURRENT_USER);
        session.invalidate();
        respMap.put("msgDesc", ERROR_VALUE_OP_RESULT_SUCCESS);

        return respMap;
    }

    /**
     * 
     * 转到密码修改页面 <br/>
     * <p>
     * Description: 转到密码修改页面 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-27-下午4:55:57<br/>
     * <p>
     * 
     * @param operatorId
     * @return
     * 
     */
    @RequestMapping("/toModifyPwdView")
    public ModelAndView toModifyPwdView(Long operatorId)
    {
        ModelAndView modelAndView = new ModelAndView("pwdModify");
        if (null != operatorId)
        {
            modelAndView.addObject("operatorId", operatorId);
        }

        return modelAndView;
    }

    /**
     * 
     * 修改用户密码 (异步请求)<br/>
     * <p>
     * Description: 修改用户密码 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-27-下午5:07:23<br/>
     * <p>
     * 
     * @param oldPwd
     * @param pwd
     * @return
     * 
     */
    @RequestMapping("modifyPwd")
    @ResponseBody
    public Map<String, String> modifyPwd(Long operatorId, String oldPwd, String pwd)
    {
        Map<String, String> respMap = null;
        try
        {
            Operator operator = _operatorService.findById(operatorId);
            if (null != operator && operator.getLoginPassword().equals(DigestUtils.md5Hex(oldPwd)))
            {
                _operatorService.modifyPassword(operatorId, DigestUtils.md5Hex(pwd));
                respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_SUCCESS, ERROR_VALUE_MSG_TYPE_INFO, "Success",
                        null);
                addLog(Visit.login, "operatorId=" + operator.getOperatorId() + "|desc=密码修改成功");
            }
            else
            {
                respMap = packageAjaxReturnMap(ERROR_VALUE_OP_RESULT_FAIL, ERROR_VALUE_MSG_TYPE_ERROR, null,
                        "你输入的旧密码不正确");
            }
        }
        catch (UppException e)
        {
            respMap = packageUppException(e);
        }
        catch (Exception e)
        {
            respMap = packageException(e);
        }
        return respMap;
    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @return
     * 
     * @see com.bcinfo.upp.admin.controller.AdminController#getMouduleCode()
     */
    public String getMouduleCode()
    {
        return Visit.moduleName.value;
    }

    /**
     * 
     * 把较色权限集合转化为map结构 <br/>
     * <p>
     * Description: 迭代较色权限集合转换为map结构 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-27-下午5:49:21<br/>
     * <p>
     * 
     * @return
     * 
     */
    private Map<Long, RolePermission> convertRolePermission(List<RolePermission> rolePerList)
    {
        if (null == rolePerList)
        {
            return null;
        }
        if (rolePerList.isEmpty())
        {
            return null;
        }
        Map<Long, RolePermission> respMap = new HashMap<Long, RolePermission>();
        for (RolePermission rolePer : rolePerList)
        {
            respMap.put(rolePer.getResourceId(), rolePer);
        }
        return respMap;
    }

    /**
     * 
     * 获取验证码验证开关 <br/>
     * <p>
     * Description: 调用远程服务获取验证码验证开关 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-5-8-下午5:44:05<br/>
     * <p>
     * 
     * @return
     * @throws UppDataBaseException
     * 
     */
    private boolean getImageCodeSwitch() throws UppDataBaseException
    {
        boolean validateSwitch = true;
        SysParameter parameter = _configureService.findByParaKey("admin_image_code_validate");
        String validateSwitchValue = null;
        if (null != parameter)
        {
            validateSwitchValue = parameter.getValue();
        }
        if (null != validateSwitchValue && "false".equalsIgnoreCase(validateSwitchValue))
        {
            validateSwitch = false;
        }

        return validateSwitch;
    }
}
